package com.zq.behavior.interpreter;

import java.util.Objects;

public interface Expression {
    boolean interpret(Context context);
}

class Variable implements Expression {
    private String name;

    Variable(String name) {
        this.name = name;
    }

    @Override
    public boolean interpret(Context context) {
        return context.lookup(this);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Variable variable = (Variable) o;
        return name.equals(variable.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name);
    }
}

class Constant implements Expression {
    private boolean val;

    Constant(boolean val) {
        this.val = val;
    }

    @Override
    public boolean interpret(Context context) {
        return val;
    }
}

class And implements Expression {
    private Expression left, right;

    And(Expression l, Expression r) {
        left = l;
        right = r;
    }

    @Override
    public boolean interpret(Context context) {
        return left.interpret(context) && right.interpret(context);
    }
}

class Or implements Expression {
    private Expression left, right;

    Or(Expression l, Expression r) {
        left = l;
        right = r;
    }

    @Override
    public boolean interpret(Context context) {
        return left.interpret(context) || right.interpret(context);
    }
}

class Not implements Expression {
    private Expression exp;

    Not(Expression e) {
        exp = e;
    }

    @Override
    public boolean interpret(Context context) {
        return !exp.interpret(context);
    }
}
